package com.tbit.main.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.OperateLog;
import com.tbit.main.constant.*;
import com.tbit.main.controller.interceptor.LoginUserContextHolder;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.service.impl.UserOpLogService;
import com.tbit.main.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * 禁停区
 *
 * @author Leon
 * 2020年4月2日 下午5:40:46
 */
@RestController
@RequestMapping("/prohibitArea")
public class ProhibitAreaController {
    @Autowired
    private ProhibitAreaService prohibitAreaService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private GeoreGionService georeGionService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private UserOpLogService userOpLogService;

    /**
     * 添加
     */
    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.FORBIDDEN, methods = MethodEnum.PROHIBITAREA_ADD)
    public JsonResult add(String token, ProhibitArea prohibitArea, Integer mapType) {

        /* 校验 */
        Assert.hasLength(prohibitArea.getName(), "ParkPoint.name.notNull");
        Assert.notNull(prohibitArea.getAllowRange(), "ParkPoint.allowRange.notNull");
        Assert.notNull(prohibitArea.getPoints(), "ParkPoint.points.notNull");
        Assert.notNull(prohibitArea.getAccountId(), "AccountUser.agentId.notNull");
        ProhibitArea prohibitAreaByName = prohibitAreaService.getByProhibitAreaName(prohibitArea.getAccountId(), prohibitArea.getName());
        if (prohibitAreaByName != null) {
            throw new BaseException("该运营区内有重复的禁停区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        /* 备注 */
        if (prohibitArea.getRemark() == null) {
            prohibitArea.setRemark("");
        }

        /** 保存原始坐标*/
        prohibitArea.setPointsC(prohibitArea.getPoints());

        /** 计算电子围栏中心点 */
        List<Point> points = GeoUtil.getPoints(prohibitArea.getPoints());
        Point newPoint = GeoUtil.GetCenterPoint(points);

        prohibitArea.setLa(newPoint.getY());
        prohibitArea.setLo(newPoint.getX());


        /** 经纬度校准 */
        calibrateService.calProhibitArea(prohibitArea, mapType, SysConstant.ORIGINAL);

        prohibitAreaService.insert(prohibitArea);

        return JsonResult.succ();
    }

    /**
     * 更新
     */
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.FORBIDDEN, methods = MethodEnum.PROHIBITAREA_EDIT)
    public JsonResult edit(String token, ProhibitArea prohibitArea, Integer mapType) {
        /* 校验 */
        Assert.notNull(prohibitArea.getProhibitAreaId(), "ParkPoint.id.notNull");
        ProhibitArea prohibitAreaByName = prohibitAreaService.getByProhibitAreaName(prohibitArea.getAccountId(), prohibitArea.getName());
        if (prohibitAreaByName != null && !Objects.equals(prohibitArea.getProhibitAreaId(), prohibitAreaByName.getProhibitAreaId())) {
            throw new BaseException("该运营区内有重复的禁停区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        /**查询停车点*/
        ProhibitArea prohibitAreaDB = prohibitAreaService.getByProhibitAreaId(prohibitArea.getProhibitAreaId());

        /**替换可修改字段*/
        ObjectUtil.assign(prohibitArea, prohibitAreaDB, null);

        /** 保存原始坐标*/
        prohibitArea.setPointsC(prohibitArea.getPoints());

        /** 计算电子围栏中心点 */
        List<Point> points = GeoUtil.getPoints(prohibitArea.getPoints());
        Point newPoint = GeoUtil.GetCenterPoint(points);

        prohibitArea.setLa(newPoint.getY());
        prohibitArea.setLo(newPoint.getX());

        /** 经纬度校准 */
        calibrateService.calProhibitArea(prohibitArea, mapType, SysConstant.ORIGINAL);

        prohibitAreaService.update(prohibitArea);

        // 插入用户操作日志
        AccountUser accountUser = LoginUserContextHolder.getLoginUser();
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(prohibitAreaDB.getAccountId())
                .opUser(accountUser.getName())
                .opUserPhone(accountUser.getPhone())
                .operation("编辑禁停区")
                .opPlatform(OperationPlatform.MANAGER.code)
                .opTime(LocalDateTime.now())
                .result(true)
                .build());

        return JsonResult.succ();
    }

    /**
     * 删除
     */
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.FORBIDDEN, methods = MethodEnum.PROHIBITAREA_DEL)
    public JsonResult del(String token, Integer prohibitAreaId) {
        /* 校验 */
        Assert.notNull(prohibitAreaId, "ParkPoint.id.notNull");

        /* 权限判断 */

        prohibitAreaService.del(prohibitAreaId);

        return JsonResult.succ();
    }

    /**
     * 根据平台账号id查询
     */
    @RequestMapping("/getByAccountId")
    public JsonResult getByAccountId(String token, Integer mapType, Integer accountId,
                                     @RequestParam(value = "regionId", required = false) List<Integer> regionId) {
        AccountUser accountUserToken = tokenService.getAccount(token);
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        if (CollUtil.isEmpty(regionId)) {
            regionId = georeGionService.getByAccountUserId(accountUserToken.getAccountUserId());
        }

        List<ProhibitArea> prohibitAreas = new LinkedList<>();
        if (CollUtil.isNotEmpty(regionId)) {
            prohibitAreas = prohibitAreaService.getByRegionId(regionId);
        } else {
            prohibitAreas = prohibitAreaService.getByAccountId(accountId);
        }

        /** 校准 */
        calibrateService.celibrateProhibitArea(prohibitAreas, mapType);

        return JsonResult.succ(prohibitAreas);
    }

    /**
     * 获取附近禁停区
     */
    @RequestMapping("/getNear")
    public JsonResult getNear(String token, Integer mapType, Integer accountId, Double lo, Double la, Integer radius,
                              @RequestParam(value = "regionId", required = false) List<Integer> regionId) {
        AccountUser accountUserToken = tokenService.getAccount(token);

        Assert.notNull(lo, "-2001", "Map.lon.nutNull");
        Assert.notNull(la, "-2002", "Map.lat.nutNull");
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        /**默认谷歌地图*/
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        /**默认1公里*/
        if (radius == null) {
            radius = 1000;
        }

        Point point = new Point(lo, la);
        point = calibrateService.commonCalibrate(point, mapType, MapConstant.MAP_ORI);


        if (CollUtil.isEmpty(regionId)) {
            regionId = georeGionService.getByAccountUserId(accountUserToken.getAccountUserId());
        }

        List<ProhibitArea> prohibitAreas = new LinkedList<>();
        if (CollUtil.isNotEmpty(regionId)) {
            prohibitAreas = prohibitAreaService.getByRegionAndArea(regionId, point.getX(), point.getY(), radius);
        } else {
            prohibitAreas = prohibitAreaService.getByAccountAndArea(accountId, point.getX(), point.getY(), radius);
        }


        /** 校准 */
        calibrateService.celibrateProhibitArea(prohibitAreas, mapType);

        return JsonResult.succ(prohibitAreas);
    }

    /**
     * 测试
     *
     * @param token
     * @param userCode
     * @return
     */
    @RequestMapping("/test")
    public JsonResult test(String token, String userCode) {

        Machine machine = machineService.getByUseCode(userCode);

        String json = redisService.getGetWay(RedisUtil.getTerHashId(machine.getMachineNO()), RedisConstant.REDIS_TER_LAST_STATUS);

        LogUtil.info("json：" + json);

        if (json != null && json.length() > 0) {
            TerLastStatus terLastStatus = JSON.parseObject(json, TerLastStatus.class);
            Integer terStatus = terLastStatus.getCarStatus();

            LogUtil.info("信息：" + terStatus);

            LogUtil.info("结果：" + ObjectUtil.statusParse(7, Integer.valueOf(terStatus)));
        }

        return JsonResult.succ();
    }
}